/*
 * Copyright (c)  2008 Sebastien Tremblay
 *
 * id3-tag-builder - helpers.TreeViewModel.java
 *
 * All source and documentation is copyrighted by Sebastien Tremblay
 * (seb at ryders dot net) and made available under the Apache License 2.0.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * $Id: TreeViewModel.java 30 2010-01-08 04:01:06Z ryders $
 */
package com.empireone.id3tagbuilder.gui.tree;

import com.empireone.id3tagbuilder.classes.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author Sebastien Tremblay
 */
public class TreeViewModel implements TreeModel {

    private Path root;// = new Path("Music Library", null);// new File("/home/sebs/workspace").listFiles(), TriStateCheckBox.State.UNCHECKED);

    private static final List<TreeModelListener> listeners = new LinkedList<TreeModelListener>();
    private final List<Path> checkedFolders = new LinkedList<Path>();
    private final List<Path> uncheckedFolders = new LinkedList<Path>();
    private final List<Path> partialFolders = new LinkedList<Path>();

    /**
     *
     * @param paths
     */
    public TreeViewModel(Vector<Path> paths) {
        Iterator<Path> it = paths.iterator();

        while (it.hasNext()) {
            Path p = (Path) it.next();
            
            if (!p.isValid()) { it.remove(); }
        }

        ArrayList<Path> children = new ArrayList<Path>(paths.size());

        it = paths.iterator();

        while (it.hasNext()) {
            children.add((Path) it.next());
        }

        root = new Path("Music Lib", children);
    }

    /**
     *
     * @param l
     */
    @Override
    public void addTreeModelListener(TreeModelListener l) {
        listeners.add(l);
    }

    /**
     *
     * @param parent
     * @param index
     * @return
     */
    @Override
    public Object getChild(Object parent, int index) {
        return ((Path) parent).getChild(index);
    }

    /**
     *
     * @param parent
     * @return
     */
    @Override
    public int getChildCount(Object parent) {
        return ((Path) parent).getChildCount();
    }

    /**
     *
     * @param parent
     * @param child
     * @return
     */
    @Override
    public int getIndexOfChild(Object parent, Object child) {
        for (int i = 0; i < ((Path) parent).getChildCount(); i++) {
            if (child == ((Path) parent).getChild(i)) {
                return i;
            }
        }
        return -1;
    }

    /**
     *
     * @return
     */
    @Override
    public Object getRoot() {
        return root;
    }

    /**
     *
     * @param node
     * @return
     */
    @Override
    public boolean isLeaf(Object node) {
        Path folder = (Path) node;
        return folder.getChildCount() == 0;
    }

    /**
     *
     * @param l
     */
    @Override
    public void removeTreeModelListener(TreeModelListener l) {
        listeners.remove(l);
    }

    /**
     * Called after the call to TreeCellEditor.getCellEditorValue(), passing the result of that method in the newValue parameter.
     * @param path
     * @param newValue
     */
    @Override
    public void valueForPathChanged(TreePath path, Object newValue) {
        Path folder = (Path) path.getLastPathComponent();
        /*folder.setState((TriStateCheckBox.State) newValue);
        if (folder.getState() == TriStateCheckBox.State.CHECKED) {
            checkedFolders.add(folder);
            uncheckedFolders.remove(folder);
        } else if (folder.getState() == TriStateCheckBox.State.PARTIAL) {
            checkedFolders.remove(folder);
            partialFolders.add(folder);
        } else {
            partialFolders.remove(folder);
            uncheckedFolders.add(folder);
        }*/
        fireModelChangedEvent(path);
    }

    /**
     * Returns the list of folders that the user manually checked. NOTE: it does
     * not contain subfolders that have been automatically checked by the
     * system.
     * @return
     */
    public List<Path> getCheckedFolders() {
        return Collections.unmodifiableList(checkedFolders);
    }

    /**
     * Returns the list of folders that the user manually unchecked (excluded).
     * NOTE: it does not contain subfolders that have been automatically
     * unchecked by the system.
     * @return
     */
    public List<Path> getUncheckedFolders() {
        return Collections.unmodifiableList(uncheckedFolders);
    }

    private void fireModelChangedEvent(TreePath path) {
        for (TreeModelListener l : listeners) {
            l.treeNodesChanged(new TreeModelEvent(this, path));
        }
    }
}
